iT邦幫忙

2025 iThome 鐵人賽

DAY 27
1
Software Development

30 天的 .Net gRPC 迷途系列 第 27

Day27 gRPC + Dapper 資料庫功能

  • 分享至 

  • xImage
  •  

Dapper 是一個輕量、快速且簡單的 ORM 工具,與 Entity Framework 等傳統 ORM 相比,它不提供複雜的物件映射與 CRUD 生成,而是以 原生 SQL 命令 + 參數化查詢 的方式直接操作資料庫,具有以下優點:

效能高:無物件映射開銷,直接使用 ADO.NET。
語法簡潔:無冗長的 LINQ 語法,減少過多層次的抽象。
安全性強:自動處理參數化查詢,有效防止 SQL 注入。
易於測試與調試:SQL 語句明確可見,方便日誌與錯誤追蹤。

(跟 EF Core 相比之下,這比較好介紹)

Nuget 套件安裝

在專案安裝以下工具,下面用 Cli 示意

// Dapper 元件
dotnet add package Dapper --version 2.1.66

// .Net SQL Client
dotnet add package Microsoft.Data.SqlClient --version 6.1.1

DI 注入

Program.cs 裡面註冊資料庫連線的 DI

// DefaultConnection 是放在 appsettings.json 裡面的資料庫連線字串
builder.Services.AddScoped<IDbConnection>(sp => new Microsoft.Data.SqlClient.SqlConnection(builder.Configuration.GetConnectionString("DefaultConnection")));

撰寫資料庫相關程式

把之前使用的 UserRepository.cs 修改成真的跟資料庫使用

public interface IUserRepository
{
    Task<User?> FindUser(string userName);
}

/// <summary>
/// 資料庫對應物件
/// </summary>
public class User
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

public class UserRepository : IUserRepository
{
    private readonly IDbConnection _connection;

    public UserRepository(IDbConnection connection)
    {
        _connection = connection;
    }

    public async Task<User?> FindUser(string userId)
    {
        var sql = "SELECT Id, Name, Price, Category FROM User WHERE Id = @Id";
        return await _connection.QueryFirstOrDefaultAsync<User>(sql, new { Id = userId });
    }
}

gRPC 端點

調整 UserService.cs

public class UserService : MyGrpcServer.UserService.UserServiceBase
{
    private readonly IUserRepository _userRepository;
    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public override async Task<GetUserResponse> GetUser(GetUserRequest request, ServerCallContext context)
    {
        var res = await _userRepository.FindUser(request.UserId);

        if (res is null)
        {
            throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, "User not found"));
        }

        return new GetUserResponse()
        {
            User = new User { Name = res.Name},
            Status = Status.Active
        };
    }
}

上一篇
Day26 gRPC 整合 .Net DI 服務
下一篇
Day28 實作 TODO List (Server)
系列文
30 天的 .Net gRPC 迷途28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言